<?php
/**
 * Image
 * Класс для загрузки изображений
 *
 * @author Дмитрий Кузьма <kouzma.d@gmail.ru>
 * @version 2.1
 */
class Image{

   private $fileArray = null;
   static $maxImageSize = 10485760;
   static $maxImageWidth = 204800; // если больше - то выкинет ошибку
   static $maxImageHeight = 153600; // если больше - то выкинет ошибку
   private $imageType = '';
   private $allowEmpty = false;
   private $goalFolder = '';
   private $goalSubFolder = '';
   private $foldersChecked = false;
   private $defaultPicturePath = null;
   private $useDefaultPath = false;

   private $arrSizes = array();
   private $arrCut = array();
   private $maxWidth = false; // задаваемая ширина - если изображение шире - то оно будет сжато до maxWidth
   private $maxHeight = false; // задаваемая высота - если изображение выше - то оно будет сжато до maxHeight
   private $newExtension = false; // в какое рнасширение преобразовывать картинку
   private $errorExists = false;
   private $fieldName;
   private $imageName = '';
   private $throwException = false;
   private $errorText = '';
   private $isLoaded = false;
   private $square = false;

   private $object = null;
   private $deleteOnChange = false;

  /**
   * Проверяет, возникала ли ошибка
   *
   * @return unknown
   */
  public function isErrorExists() {
  	return $this->errorExists;
  }

  public function __construct($fieldName, $fileArray, $arrSettings = null, $obj = null) {
  	if($arrSettings) foreach ($arrSettings as $settingName => $settingValue) {
  		$this->setSetting($settingName, $settingValue);
  	}
  	$this->setFieldName($fieldName);
  	if($obj) $this->object = $obj;
  	if (!$this->allowEmpty)
  		$this->setFileArray($fileArray);

  }

	/**
	 * Метод устанавливает свойство (поисковое)
	 *
	 * @param string $settingName
	 * @param mixed $settingValue
	 */
	public function setSetting($settingName, $settingValue){
		switch ($settingName) {
			/*case 'file': case 'array':
				$this->setFileArray($settingValue);
				break;*/
			case 'folder':
				$this->setGoalFolder($settingValue);
				break;
			case 'subFolder':case 'subfolder':
				$this->setGoalSubFolder($settingValue);
				break;
			case 'imageName':
				$this->setImageName($settingValue);
				break;
			case 'imageType':
				$this->imageType = $settingValue;
				break;
			case 'square':
				$this->square = true;
				break;
				/*
			case 'field': case 'fieldName':
				$this->setFieldName($settingValue);
				break;
				*/
			case 'allowEmpty':
				$this->setAllowEmpty($settingValue);
				break;
			case 'defaultPath':
				$this->setDefaultPath($settingValue);
				break;
			case 'sizes':
				$this->setArrSizes($settingValue);
				break;
			case 'cut':
				$this->setArrCut($settingValue);
				break;
			case 'deleteOnChange':
				$this->deleteOnChange = $settingValue;
				break;
			case 'maxWidth':
				$this->maxWidth = $settingValue;
				break;
			case 'maxHeight':
				$this->maxHeight = $settingValue;
				break;
			case 'newExtension':
				$this->newExtension = $settingValue;
				break;
			case 'exception':
				$this->throwException = $settingValue;
				break;

			default:
				throw new Exception('Вы пытаетесь использовать недопустимые настройки (' . $settingName . '). К допустим настройкам относятся: "sizes", "folder", "subFolder", "imageName"');
				break;
		}
	}




  private function throwImageError($text){
    	$this->errorExists = true;
    	$this->errorText = $text;//'Вы закачиваете слишком большой файл! Файл должен быть не больше ' . (self::$maxImageSize/1024) . 'килобайт.';

//    	if(isset($this->fieldName)) {
    		throw new Exception($this->errorText);
//    		if(isset($this->object) && get_class($this->object)) Exception_ActiveRecord::addObjectException(get_class($this->object), $this->fieldName, $this->errorText);
//    	}
//    	if ($this->throwException) throw new Exception($this->errorText);
  }


  /**
   * проверяет насколько файл соответствует требованиям
   */
  public function checkUploadFile() {
  	//Проверка загрузки файла
    if (($this->fileArray['error']) == 1 ) { // проверка на размер закачиваемо файла
    	$this->throwImageError('Вы закачиваете слишком большой файл! Файл должен быть не больше ' . (self::$maxImageSize/1024) . 'килобайт.');
    	return false;
    }
    if (($this->fileArray['error']) == 4 ) {// проверка если файл для закачки не выбран
    	if ($this->allowEmpty) {
    	  if($this->defaultPicturePath) {
    	  	$this->useDefaultPath = true;
    	  }
    		else
    		  return false;
    	}
    	else {
    		$this->throwImageError('Файл не был загружен, возможно, вы его не выбрали.');
    		return false;
    	}
    }
    if (($this->fileArray['error']) == 3 ) { // проверка на ошибку в процессе закачки файла
    	$this->throwImageError('Произоша ошибка при загрузке файла, Попробуйте снова !!!');
    	return false;
    }

    if ($this->fileArray['size'] > self::$maxImageSize) {
      $this->throwImageError('Вы закачиваете слишком большой файл! Файл должен быть не больше ' . (self::$maxImageSize/1024) . 'килобайт.');
    	return false;
    }

    list($width, $height) = getimagesize($this->useDefaultPath ? $this->defaultPicturePath : $this->fileArray['tmp_name']);// получение размеров изображения
    if ( ($width > self::$maxImageWidth) || ($height > self::$maxImageWidth)) {
      $this->throwImageError('Вы закачиваете слишком большое изображение! Изображение должно быть не больше, чем ' . self::$maxImageWidth . ' на ' . self::$maxImageHeight .' px.');
    	return false;
    }
    if($this->useDefaultPath){
      $size = getimagesize($this->defaultPicturePath);
      $mimeType = $size['mime'];
    }
    else
      $mimeType = $this->fileArray['type'];

    //Проверка расширения файла
    switch ($mimeType) {
      case 'image/jpeg': case 'image/pjpeg':
        $this->imageType = 'jpg';
        break;
      case 'image/gif':
        $this->imageType = 'gif';
        break;
      case 'image/x-png': case 'image/png':
        $this->imageType = 'png';
        break;
      case 'image/tiff':
        $this->imageType = 'tiff';
        break;        
      default:
        $this->throwImageError('Такой тип файла не поддерживается.');
    		return false;
    }
    $this->isLoaded = true;
    return true;
  }



  /**
   * вращает массив с размерами изображения согласно сжатию
   *
   * @param integer $widthSrc
   * @param integer $heightSrc
   * @param integer $widthDist
   * @param integer $heightDist
   * @return array
   */
  private function getCutImageCoords($widthSrc, $heightSrc, $widthDist, $heightDist, $photos_for_album = false, $cut = '') {
  	
  	// сохраняем оригинальный размер
  	if ($widthDist == 0 && $heightDist == 0)
  		return array(0, 0, $widthSrc, $heightSrc);
  	
  	// сохраняем размер по одной заданной стороне (пропорционально)
  	if ($widthDist == 0 || $heightDist == 0){
  		if ($photos_for_album && $heightSrc > $widthSrc){
  			// если это высокая фотка
			if ($widthDist == 0 && $cut != ''){ // если будем обрезать, то подготавливаем новые размеры
				$scale = $heightDist / $widthSrc; // коэфф масштабирования = 64 - уменьшить
				
				$prop = $heightSrc / $widthSrc; // исходные пропорции изображения 
				
				$widthDist = ceil($heightSrc * $scale); // итоговая ширина - 94.5px
				
  				$widthCut = $widthSrc; // вырезаем по всей исходной ширине
  				$heightCut = ceil($heightDist / $scale / $prop); // получаем высоту в исходном разрешении, которую вырежем
  				
  				
  				if ($cut == 'cut_bottom'){ // отрезаем нижнию часть
  					$src_x = 0; // левый верхний угол
  					$src_y = 0; // левый верхний угол
  				}elseif ($cut == 'cut_header'){ // отрезаем верх
  					$src_x = 0; // левый нижний угол
  					$src_y = ceil($heightSrc - $heightCut);
  				}
  				
  				return array($src_x, $src_y, $widthCut, $heightCut);
  			}
  		}
  		else{
			return array(0, 0, $widthSrc, $heightSrc); // оставляем параметры - без обрезки
  		}
  	}
  			
    $widthKoef = $widthSrc / $widthDist;
    $heightKoef = $heightSrc / $heightDist;
  	if(!$this->square && ($widthKoef >= 1 || $heightKoef >= 1)) {
	    return array(0, 0, $widthSrc, $heightSrc);
    }
    elseif($this->square) {
			$mainKoef = min($widthKoef, $heightKoef);
			$mainKoef = max($mainKoef, 1);
			$cutWidth = $mainKoef * $widthDist;
			$cutHeight = $mainKoef * $heightDist;
			$width_1 = ($widthSrc - $cutWidth) / 2;
			//$width_2 = $width_1 + $cutWidth;
			$height_1 = ($heightSrc - $cutHeight) / 2;
			//$height_2 = $height_1 + $cutHeight;
			return array($width_1, $height_1, $cutWidth, $cutHeight);
    	/*if($widthKoef >= 1 && $heightKoef >= 1) {
				$newWidth = $widthDist;
				$newHeight = $heightDist;

				if($widthKoef >= $heightKoef) {
					$startWidth = $heightKoef *
				}
				else {

				}
			}
			else {
				if($widthKoef < 1)
				  return array($widthSrc, $heightDist);
				else
				  return array($widthDist, $heightSrc);
			}*/
    }
    else { //Если картинка очень маленькая
    	return array(0, 0, $widthSrc, $heightSrc);
    }
  }
  /**
   * вращает массив с размерами изображения согласно сжатию
   *
   * @param integer $widthSrc
   * @param integer $heightSrc
   * @param integer $widthDist
   * @param integer $heightDist
   * @return array
   */
  private function getNewImageSizes($widthSrc, $heightSrc, $widthDist, $heightDist, $photos_for_album = false, $cut = '') {
    
	if ($this->maxWidth || $this->maxHeight){
		if ($this->maxWidth){
			if ($widthSrc > $this->maxWidth){ // если надо сжимать
				$scale = $this->maxWidth / $widthSrc;
				return array(ceil($widthSrc * $scale), ceil($heightSrc * $scale));
			}
			else return array($widthSrc, $heightSrc);
		}
		elseif ($this->maxHeight){
			if ($heightSrc > $this->maxHeight){ // если надо сжимать
				$scale = $this->maxHeight / $heightSrc;
				return array(ceil($widthSrc * $scale), ceil($heightSrc * $scale));
			}
			else return array($widthSrc, $heightSrc); 			
		}
	}
	
	// сохраняем оригинальный размер
  	if ($widthDist == 0 && $heightDist == 0)
  		return array($widthSrc, $heightSrc);
  	
  	// сохраняем размер по одной заданной стороне (пропорционально)
  	if ($widthDist == 0 || $heightDist == 0){
  		if ($photos_for_album && $heightSrc > $widthSrc){
  			// если это высокая фотка
  			if ($heightDist == 0){ // и задана ширина сохранения, то ширину придется изменить чтоб в альбоме было красиво
  				// то задаем оптимальную высоту
  				$prop = $heightSrc / $widthSrc; // исходные пропорции изображения
  				$scale1 = $widthDist / $heightSrc; // меняем местами высоту и ширину
  				$heightDist = ceil($widthSrc * $scale1); // получаем нужную высоту, такую же, как была бы у широкой картинки
  				$widthDist = ceil($heightDist / $prop); // получаем нужную ширину, будет меньше, чем у широкой картинки
  				return array($widthDist, $heightDist);
  			}
  			elseif ($widthDist == 0 && $cut == ''){ // высокая фотка и задана высота сохранения, без обрезки
				$scale = $heightDist / $heightSrc;
				return array(ceil($widthSrc * $scale), ceil($heightSrc * $scale));
				// то так и оставляем  				
  			}
  			elseif ($widthDist == 0 && $cut != ''){ // если будем обрезать, то подготавливаем новые размеры
  				$scale1 = $heightDist / $widthSrc; 
  				$prop = $heightSrc / $widthSrc; // исходные пропорции изображения
  				$heightDist = ceil($widthSrc * $scale1); // получаем обратно заданную высоту
//  				$widthDist = ceil($heightDist / $prop);
  				$widthDist = ceil($heightSrc * $scale1); // получаем ширину как у обычной широкой картинки
  				return array($widthDist, $heightDist);
  			}
  		}
  		else{
	  		if ($heightDist == 0){
	  			$scale = $widthDist / $widthSrc;
	  			return array(ceil($widthSrc * $scale), ceil($heightSrc * $scale));
	  		}elseif ($widthDist == 0){
				$scale = $heightDist / $heightSrc;
				return array(ceil($widthSrc * $scale), ceil($heightSrc * $scale)); 			
	  		}
  		}
  	}
  	
    $widthKoef = $widthSrc / $widthDist;
    $heightKoef = $heightSrc / $heightDist;	
	
  	if(!$this->square && ($widthKoef >= 1 || $heightKoef >= 1)) {
	    if ( ($widthKoef <=1) && ($heightKoef <=1) )// сжимать не требуется
	      return array($widthSrc, $heightSrc);
	    if ($widthKoef > $heightKoef)// сжимаем в основном по ширине
	      return array($widthSrc/$widthKoef, $heightSrc/$widthKoef);
	    else        // сжимаем в основном по высоте
	      return array($widthSrc/$heightKoef, $heightSrc/$heightKoef);
    }
    elseif($this->square) {
		if($widthKoef >= 1 && $heightKoef >= 1) {
			return array($widthDist, $heightDist);
		}
		else {
			if($widthKoef < 1)
			  return array($widthSrc, $heightDist);
			else
			  return array($widthDist, $heightSrc);
		}
    }
    else { // Загружаем очень маленькую картину
    	return array($widthSrc, $heightSrc);
    }
  }


  /**
   * вращает полный путь к папке сохранения
   *
   * @return string
   */
  public function getFullFolderPath() {

    return $this->goalFolder . (($this->goalSubFolder !='') ? ($this->goalSubFolder . '/') : '');
  }


  /**
   * Метод  проверяет наличие необходимых директорий
   * при необходимости метод создает соответствующие папки
   *
   */
  public function checkFolders() {
  	if (!is_dir($this->goalFolder))
      throw new Exception('Неверно указана целевая директория');

    $currentGoalFolder = $this->goalFolder;

    if ($this->goalSubFolder != '') {
      $currentGoalFolder .= $this->goalSubFolder . '/';
      if (!is_dir($currentGoalFolder))
        if (!mkdir($currentGoalFolder))
          throw new Exception('Невозможно создать директорию для закачки.');
    }

  }

  /**
   * возвращает новое название файла. Если оно еще не было задано, то возвращается название из массива FILES
   *
   * @return string
   */
  public function getImageName() {
    if ($this->imageName == ''){

    	$this->setImageName();
    }
    if ($this->newExtension)
    	return $this->imageName . '.' . $this->newExtension;
    else 
    	return $this->imageName . '.' . $this->imageType;
  }

  /**
   * Возвращает расширение изображения
   *
   * @return string
   */
  public function getImageExtension() {
    return $this->imageType;
  }








































  /**
   * Метод создает изображение из закачанного файла
   *
   */
  public function createImageFromFile($prefix, $blockWidth, $blockHeight, $photos_for_album = false, $cut = '') {
    if (!$this->foldersChecked)
      $this->checkFolders();
    $srcFile = $this->useDefaultPath ? $this->defaultPicturePath : $this->fileArray['tmp_name'];
    // если работаем с уже загруженным файлом
    if (!file_exists($srcFile)) $srcFile = $this->goalFolder.$this->imageName.".".$this->imageType;
    
    if (!file_exists($srcFile)) throw new Exception('Ошибка при открытии изображения <br />');
    list($width, $height) = getimagesize($srcFile);// получение размеров изображения

    $srcImage = $this->imageCreateFrom($srcFile);
    if ( !$srcImage)
      throw new Exception('Ошибка при открытии изображения <br />');

    list($newWidth, $newHeight) = $this->getNewImageSizes($width, $height, $blockWidth, $blockHeight, $photos_for_album, $cut);// получение новых размеров изображения
    list($src_x, $src_y, $cutWidth, $cutHeight) = $this->getCutImageCoords($width, $height, $blockWidth, $blockHeight, $photos_for_album, $cut);// получение новых размеров изображения
    
	if($this->imageType != 'png') {
		  // создание нового изображения по размерам
		  $newImage = imagecreatetruecolor($newWidth, $newHeight);
		  if (!$newImage)
		  throw new Exception('Ошибка при создании изображения');
		  imagecopyresampled($newImage, $srcImage, 0, 0, $src_x, $src_y, $newWidth, $newHeight, $cutWidth, $cutHeight);
		  if (! $this->imageSave($newImage, $prefix . $this->getImageName()))
		    throw new Exception('Не удалось сохранить изображение с новыми размерами');

    }
    else {
		  // создание нового изображения по размерам
		  $newImage = self::imageResizeAlpha($srcImage, $newWidth, $newHeight);
		  if (!$newImage)
		  throw new Exception('Ошибка при создании изображения');
		  //imagecopyresampled($newImage, $srcImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
		  if (! $this->imageSave($newImage, $prefix . $this->getImageName()))
		    throw new Exception('Не удалось сохранить изображение с новыми размерами');
    }
    
	chmod($this->getFullFolderPath() . $prefix . $this->getImageName(), 0666);
	
    imagedestroy($newImage);
    imagedestroy($srcImage);
  }

  /**
   * Метод создает вырезанное изображение из закачанного файла
   *
   */
  public function createCutImageFromFile($prefix, $blockWidth, $blockHeight, $start_width, $start_height, $width, $height) {
    if (!$this->foldersChecked)
      $this->checkFolders();
    // берем оригинальный файл  
    $srcFile = $this->getFullFolderPath(). 'o_' . $this->getImageName();

    $srcImage = $this->imageCreateFrom($srcFile);
    if ( !$srcImage)
      throw new Exception('Ошибка при открытии изображения <br />');

	$scale = $blockWidth/$width;
	
	$newWidth = ceil($width * $scale);
	$newHeight = ceil($height * $scale);

	
    
    list($src_x, $src_y, $cutWidth, $cutHeight) = $this->getCutImageCoords($width, $height, $blockWidth, $blockHeight);// получение новых размеров изображения

	// создание нового изображения по размерам
	$newImage = imagecreatetruecolor($newWidth, $newHeight);
	if (!$newImage)
		throw new Exception('Ошибка при создании изображения');
	imagecopyresampled($newImage, $srcImage, 0, 0, $start_width, $start_height, $newWidth, $newHeight, $width, $height);
	if (! $this->imageSave($newImage, $prefix . $this->getImageName()))
		throw new Exception('Не удалось сохранить изображение с новыми размерами');

	chmod($this->getFullFolderPath() . $prefix . $this->getImageName(), 0666);
		
    imagedestroy($newImage);
    imagedestroy($srcImage);
  }  

  /**
   * Создает изображение соответствующего типа
   *
   * @param string $filePath
   */
  private function imageCreateFrom($filePath) {
    switch ($this->imageType) {
      case 'jpg':
        return imagecreatefromjpeg($filePath);
      case 'gif':
        return imagecreatefromgif ($filePath);
      case 'png':
        return imagecreatefrompng($filePath);
      case 'bmp':
        return imagecreatefromwbmp($filePath);
    }
  }

 /**
  * Метод  перемещает файл с изображением в нужную директорию
  * при необходимости метод создает соответствующие папки
  *
  */
  public  function saveExistingFile() {
    if (!$this->foldersChecked)
      $this->checkFolders();
    if (!copy(($this->useDefaultPath ? $this->defaultPicturePath : $this->fileArray['tmp_name']), $this->getFullFolderPath() . $this->getImageName()))
      throw new Exception('Невозможно скопировать закаченный файл');
  }


  /**
   * Сохраняет изображение на жесткий диск
   *
   * @param resource $image
   * @return bool
   */
  private function imageSave($image, $newFileName) {
  	$imageType = $this->imageType;
  	if ($this->newExtension)
  		$imageType = $this->newExtension;
    switch ($imageType) {
      case 'jpg':
        return imagejpeg($image, $this->getFullFolderPath(). $newFileName, 100); // качество - 100%
      case 'gif':
        return imagegif($image, $this->getFullFolderPath() . $newFileName);
      case 'png':
        return imagepng($image, $this->getFullFolderPath() . $newFileName, 0); // компрессия - 0 уровень
      case 'bmp':
        return imagewbmp($image, $this->getFullFolderPath() . $newFileName);
    }
  }

  /**
   * Устанавливаем целевую директорию для загрузки файлов
   *
   * @param string $folder
   */
  public function setGoalFolder($folder) {
    $this->goalFolder = $folder;
    $this->foldersChecked = false;
  }
  /**
   * Устанавливаем целевую поддиректорию для загрузки файлов
   *
   * @param string $subFolder
   */
  public function setGoalSubFolder($subFolder) {
    $this->goalSubFolder = $subFolder;
    $this->foldersChecked = false;
  }

  /**
   * Устанавливаем название поля ввода
   *
   * @param string $fieldName
   */
  public function setFieldName($fieldName) {
    $this->fieldName = $fieldName;
  }


  /**
   * Устанавливаем массив из  Files из которого происходит загрузка
   *
   * @param string $fileArray
   */
  public function setFileArray($fileArray) {
    $this->fileArray = $fileArray;
    return $this->checkUploadFile();
  }
  /**
   * Метод возвращает размер загружаемого файла
   *
   * @return integer
   */
  public function getFileSize() {
    if(isset($this->fileArray['size']))
      return $this->fileArray['size'];
    else
      return null;
  }
  /**
   * Устанавливаем обязательно ли должен быть заполнен массив Files
   *
   * @param bool $allowEmpty
   */
  public function setAllowEmpty($allowEmpty) {
    $this->allowEmpty = $allowEmpty;
  }
  /**
   * Устанавливаем путь для файлов по умолчанию
   *
   * @param string $defaultPath
   */
  public function setDefaultPath($defaultPath) {
    $this->defaultPicturePath = $defaultPath;
  }
  /**
   * Устанавливаем, в какаих размерах должно быть сохранено изображение
   *
   * @param array $arrSizes
   */
  public function setArrSizes($arrSizes) {
    $this->arrSizes = $arrSizes;
  }
  /**
   * Устанавливаем, в какаих размерах (cut размер) должно быть сохранено изображение
   *
   * @param array $arrSize
   */
  public function setArrCut($arrCut) {
    $this->arrCut = $arrCut;
  }     
  /**
   * Устанавливаем, в какаих размерах должно быть сохранено изображение
   *
   * @param array $arrSize
   */
  public function addArrSize($width, $height, $prefix, $photos_for_album = false, $cut = '') {
  	$this->arrSizes[] = array($width, $height, $prefix, $photos_for_album, $cut);
  }
  /**
   * Устанавливаем, в какаих размерах (cut размер) должно быть сохранено изображение
   *
   * @param array $arrSize
   */   
  public function addArrCut($Block_width, $Block_height, $prefix, $start_width, $start_height, $width, $height){
	$this->arrCut[] = array($Block_width, $Block_height, $prefix, $start_width, $start_height, $width, $height);
  }

  /**
   * Возвращает случайное имя
   *
   * @param integer $simbols
   * @return string
   */
  public static function randomName($simbols = 16) {
  	return substr(md5(time()), 0, $simbols);
  }
  /**
   * Формирует массив данных для сохранения в БД информации об изображении
   *
   * @return array
   */
  public function dbGetArrToSave() {
  	$retArr = array();
  	$retArr['pic_folder'] = $this->getFullFolderPath();
  	$retArr['pic_file'] = $this->getImageName();
  	list($retArr['pic_width'], $retArr['pic_height']) = getimagesize($this->useDefaultPath ? $this->defaultPicturePath : $this->fileArray['tmp_name']);// получение размеров изображения
		return $retArr;
  }
  /**
   * Задает название фала для сохранения. По умолчанию создается рендомный файл
   *
   * @param string $name
   */
  public function setImageName($name = null) {
  	if(!$name) {
  		$this->imageName = $this->randomName();
  		//if(file_exists(substr($this->getFullFolderPath(), strlen(W_ABSPATH)) . $this->getImageName()))
  		if(file_exists($this->getFullFolderPath() . $this->getImageName()))
	  		$this->setImageName();

  	}
  	else {
//    	$this->throwImageError('Файл с таким именем уже существует.');
  		$this->imageName = $name;
  	}
  }
  /**
   * Метод сохраняет новый набор изображений
   *
   */
  public function save() {
  	if($this->deleteOnChange){
  		if(isset($this->object->id) && $this->object->id) {
  			$arrImageToDelete = $this->getObjectPicture($this->object);
  		}
  	}
  	if (sizeof($this->arrSizes) != 0){
	  	foreach ($this->arrSizes as $arrSize) {
//			if($arrSize[1])
			$this->createImageFromFile($arrSize[2], $arrSize[0], $arrSize[1], $arrSize[3], $arrSize[4]);
/*			else
			  $this->saveExistingFile();*/
			if($this->deleteOnChange) { //Удаляем старый файл
			  if(file_exists($arrImageToDelete['pic_folder'] . (isset($arrSize[2]) ? $arrSize[2] : null) . $arrImageToDelete['pic_file']))
			    unlink($arrImageToDelete['pic_folder'] . (isset($arrSize[2]) ? $arrSize[2] : null) . $arrImageToDelete['pic_file']);
			}
	  	}
  	}
  	if (sizeof($this->arrCut) != 0){
  		foreach ($this->arrCut as $arrCut){
  			$this->createCutImageFromFile($arrCut[2], $arrCut[0], $arrCut[1], $arrCut[3], $arrCut[4], $arrCut[5], $arrCut[6]);
  		}
  	}
  	

  }
  /**
   * Проверяет, загрузилась ли картинка
   *
   * @return bool
   */
  public function isLoaded() {
  	return $this->isLoaded;
  }

  /**
   * Выводит зображения по сохраненному шаблону
   *
   * @param string $folder
   * @param string $file
   * @param string $type
   */
  public function showSavedImage($folder, $file, $type = '', $style = '') {
  	echo '<img src="' . W_ABSPATH . $folder . $type . $file . '" class="savedImage" style="' . $style . '" alt="" />';
	}

	/**
	 * Получает массив с информацией о картинке объекта
	 *
	 * @param object $objAR
	 * @return array
	 */
	public function getObjectPicture($objAR) {
		$objDB = Service_Database::instance();// Получаем подключение к БД
		$stmt = "SELECT `pic_folder`, `pic_file`, `pic_width`, `pic_height` FROM `" . $objAR->tableName . "` WHERE `" . $objAR->pkName . "`='" . $objAR->id . "'";
		return $objDB->selectOne($stmt);
	}

	/**
	 * Удаляет аватары элемента
	 *
	 * @param string $folder
	 * @param string $baseFile
	 */
	public static function deleteAvatarOfElement($folder, $baseFile) {
		if(file_exists($folder . '' . $baseFile) && is_file($folder . '' . $baseFile))
		  unlink($folder . '' . $baseFile);
		if(file_exists($folder . 's_' . $baseFile) && is_file($folder . 's_' . $baseFile))
		  unlink($folder . 's_' . $baseFile);
		if(file_exists($folder . 'm_' . $baseFile) && is_file($folder . 'm_' . $baseFile))
		  unlink($folder . 'm_' . $baseFile);
		if(file_exists($folder . 'b_' . $baseFile) && is_file($folder . 'b_' . $baseFile))
		  unlink($folder . 'b_' . $baseFile);
	}




  /**
   * Метод создает изображение из закачанного файла
   *
   */
  public static function createImageFromUploadedFile($path, $name ,$extension, $prefix, $blockWidth, $blockHeight, $square = 0, $watermark = false) {
		$im = $path . $name . '.' . $extension;
    list($width, $height) = getimagesize($im);// получение размеров изображения
    $srcImage = imagecreatefromjpeg($im);
/*
    switch ($extension) {
      case 'jpg':  case 'jpeg':
        $srcImage = imagecreatefromjpeg($im);
        break;
      case 'gif':
        $srcImage = imagecreatefromgif ($im);
        break;
      case 'png':
        $srcImage = imagecreatefrompng($im);
        break;
      case 'bmp':
        $srcImage = imagecreatefromwbmp($im);
    }*/
		if ($square && $width >= $blockWidth && $height >= $blockHeight ) {
	    if ($width > $height) {
				$newWidth = $newHeight = $blockHeight;
				$newImage = imagecreatetruecolor($newWidth, $newHeight);
				imagecopyresampled($newImage, $srcImage, 0, 0, ($width - $height)/2, 0,$newWidth, $newHeight, $height, $height);
	    }
			else {
				$newWidth = $newHeight = $blockWidth;
				$newImage = imagecreatetruecolor($newWidth, $newHeight);
				imagecopyresampled($newImage, $srcImage, 0, 0, 0, ($height - $width)/2, $newWidth, $newHeight, $width, $width);
			}

		}
		else {
	    $widthKoef = $width / $blockWidth;
	    $heightKoef = $height / $blockHeight;
	    if ( ($widthKoef <=1) && ($heightKoef <=1) )// сжимать не требуется
	      list($newWidth, $newHeight) =  array($width, $height);
	    elseif ($widthKoef > $heightKoef)// сжимаем в основном по ширине
	      list($newWidth, $newHeight) =  array($width/$widthKoef, $height/$widthKoef);
	    else        // сжимаем в основном по высоте
	      list($newWidth, $newHeight) =  array($width/$heightKoef, $height/$heightKoef);
	    // создание нового изображения по размерам
	    $newImage = imagecreatetruecolor($newWidth, $newHeight);
	    imagecopyresampled($newImage, $srcImage, 0, 0, 0, 0,$newWidth, $newHeight, $width, $height);
		}
    if ($watermark) {
    	list($wmWidth, $wmHeight) = getimagesize($watermark);
    	$watermarkImage = imagecreatefrompng($watermark);
    	imagecopy($newImage, $watermarkImage, $newWidth-$wmWidth, $newHeight-$wmHeight, 0, 0,$wmWidth, $wmHeight);
    }
		$newFileName = $path . $prefix . $name . '.' . $extension;
    switch ($extension) {
      case 'jpg':  case 'jpeg':
        imagejpeg($newImage, $newFileName);
        break;
      case 'gif':
        imagegif($newImage, $newFileName);
        break;
      case 'png':
        imagepng($newImage, $newFileName);
        break;
      case 'bmp':
        imagewbmp($newImage, $newFileName);
    }
    imagedestroy($newImage);
    imagedestroy($srcImage);
  }

	/**
	* Создание png из исходного файла
	* если заданы новые ширина и высота, тоггда ресайзим PNG (и сохраням всю информацию о прозрачностях)
	*/
	public static function imageComposeAlpha( &$src, &$ovr, $ovr_x, $ovr_y, $ovr_w = false, $ovr_h = false)
	{
		if( $ovr_w && $ovr_h )
			$ovr = imageResizeAlpha( $ovr, $ovr_w, $ovr_h );

		//Соединяем 2 изображенич
		imagecopy($src, $ovr, $ovr_x, $ovr_y, 0, 0, imagesx($ovr), imagesy($ovr) );
	}

	/**
	* Изменения размеров png с прозрачностью с учетом заданных размеров
	* с сохранением информации об альфа-каналах прозрачности
	*/
	public static function imageResizeAlpha(&$src, $w, $h)
	{
		//Создаем новое изображение согласно ширине и высоте
		$temp = imagecreatetruecolor($w, $h);

		//Создание нового прозрачного изображения
		$background = imagecolorallocate($temp, 0, 0, 0);
		ImageColorTransparent($temp, $background); //Создание нового полностью прозрачного изображения
		imagealphablending($temp, false); // Отключаем альфа-смешение, чтобы сохранить альфа-канал (прозрачность)

		//Изменяем размеры png-файла
		/* use imagecopyresized to gain some performance but loose some quality */
		//используем метод imagecopyresized - выигрываем в производительности, теряя в качестве
		//imagecopyresized($temp, $src, 0, 0, 0, 0, $w, $h, imagesx($src), imagesy($src));
		//используем метод imagecopyresampled - выигрываем в качестве, теряя в производительности
		imagecopyresampled($temp, $src, 0, 0, 0, 0, $w, $h, imagesx($src), imagesy($src));
		return $temp;
	}

	/**
	 * Метод определяет маргины для того, чтобы вписать картинку в прямоугольник точно по центру и размеры изображения
	 *
	 * @param string $file
	 * @param string $folder
	 * @param string $prefix
	 * @param integer $blockWidth
	 * @param integer $blockHeight
	 * @return mixed
	 */
	public static function getImageBlockPositionInfo($file, $folder = null, $prefix = null, $blockWidth = 0, $blockHeight = 0, $onlyStyle= true) {
		if(!file_exists($folder . $prefix . $file))
		  return null;
		  $imageFile = $folder . $prefix . $file;
	  list($imageWidth, $imageHeight) = getimagesize($imageFile);
	  $styleText = 'width:' . $imageWidth . 'px;' . 'height:' . $imageHeight . 'px;';
	  if($blockWidth) {
	  	$marginHor = floor(($blockWidth - $imageWidth) / 2);
	  	$marginVert = floor(($blockHeight - $imageHeight) / 2);
	  	$styleText .= 'margin-left:' . $marginHor . 'px;' .  'margin-top:' . $marginVert . 'px;';
	  }
	  else {
	  	$marginHor = 0;
	  	$marginVert = 0;
	  }

		if($onlyStyle)
			return $styleText;
		else
		  return array($marginHor, $marginVert, $imageWidth, $imageHeight, $styleText);
	}
}
?>